<template>
  <view class="listen__ctrl">
    <!-- 进度条 -->
    <view class="listen__ctrl-slider-container">
      <Slider
        v-model="currentValue"
        :use-slot="true"
        active-color="#00d4c6"
        inactive-color="#dff7f6"
        class="listen__ctrl-slider"
      >
        <view class="listen__ctrl-slider-wrap">
          <view class="listen__ctrl-slider-circle"></view>
        </view>
      </Slider>
      <view class="listen__ctrl-slider-time">
        <view class="left">{{ currentTime | formatTime }}</view>
        <view class="right">{{ totalTime | formatTime }}</view>
      </view>
    </view>
    <!-- 控制按钮 -->
    <view class="listen__ctrl-btns">
      <view class="listen__ctrl-btns-item" @click="gotoBookDetail">
        <text class="iconfont icon-yuedu" />
        <text class="listen__ctrl-btns-item-text">去阅读</text>
      </view>
      <text class="iconfont icon-pre" @click="handleSwitchChapter('pre')" />
      <view class="listen__ctrl-btns-center" @click="handlePauseOrPlay">
        <text v-if="!playing" class="iconfont icon-play" />
        <text v-else class="iconfont icon-stop" />
      </view>
      <text class="iconfont icon-next" @click="handleSwitchChapter('next')" />
      <view class="listen__ctrl-btns-item" @click="openTimePicker">
        <text class="iconfont icon-shichang" />
        <text class="listen__ctrl-btns-item-text">定时</text>
      </view>
    </view>
    <!-- 时间选择器 -->
    <Picker
      :value="showTimePicker"
      mode="selector"
      :range="playTimeRange"
      :default-selector="[4]"
      @confirm="handleSelectPlayTime"
      @cancel="handleSelectCancel"
    />
  </view>
</template>

<script>
import Slider from '@/components/Slider';
import Picker from '@/components/picker';
import { mapState } from 'vuex';
import { get } from 'utils/index';

const playTimeArr = [
  {
    text: '5分钟',
    time: 5 * 60 * 1000,
  },
  {
    text: '10分钟',
    time: 10 * 60 * 1000,
  },
  {
    text: '15分钟',
    time: 15 * 60 * 1000,
  },
  {
    text: '20分钟',
    time: 20 * 60 * 1000,
  },
  {
    text: '30分钟',
    time: 30 * 60 * 1000,
  },
  {
    text: '1小时',
    time: 60 * 60 * 1000,
  },
  {
    text: '2小时',
    time: 120 * 60 * 1000,
  },
];

export default {
  components: {
    Slider,
    Picker,
  },

  filters: {
    formatTime(msTime) {
      let time = msTime / 1000;
      let hour = Math.floor(time / 60 / 60);
      hour = hour.toString().padStart(2, '0');
      let minute = Math.floor(time / 60) % 60;
      minute = minute.toString().padStart(2, '0');
      let second = Math.floor(time) % 60;
      second = second.toString().padStart(2, '0');
      return `${hour}:${minute}:${second}`;
    },
  },

  data() {
    return {
      currentValue: 0,
      currentTime: 0,
      playing: false,
      showTimePicker: false,
      playEndTime: 'n+', // 自动播放结束时间
    };
  },

  computed: {
    ...mapState({
      bookid: (state) => state.listen.bookid,
      chapterNum: (state) => state.listen.chapterNum,
      chapterIndex: (state) => state.listen.chapterIndex,
      voices: (state) => state.listen.voices,
    }),

    // 已播放时长
    hasPlayTime() {
      if (this.voices.slice(0, this.chapterIndex).length === 0) return 0;
      return this.voices
        .slice(0, this.chapterIndex)
        .map((item) => item.time * 1000)
        .reduce((total, cur) => total + cur);
    },

    // 总播放时长
    totalTime() {
      if (this.voices.length === 0) return 0;
      return this.voices
        .map((item) => item.time * 1000)
        .reduce((total, cur) => total + cur);
    },

    playTimeRange() {
      return playTimeArr.map((item) => item.text);
    },
  },

  watch: {
    voices(newValue) {
      if (newValue instanceof Array) {
        // 实例化音频容器
        this.audios = newValue.map((item, index) => {
          // 只加载当前章节
          if (index === this.chapterIndex) {
            return this.createAudioContext(item.url);
          } else {
            // 其他的如果已加载就复制过来
            if (this.audios[index]) return this.audios[index];
          }
        });

        // 初始化已播放时长
        this.currentTime = this.hasPlayTime;
        this.currentValue = (this.hasPlayTime / this.totalTime) * 100;
        // 2s后自动开始播放
        setTimeout(() => {
          const audioContext = this.audios[this.chapterIndex];
          if (audioContext) {
            audioContext.play();
            this.playing = true;
          }
        }, 2000);
      }
    },
  },

  created() {
    // 初始化audioContext容器
    this.audios = [];
  },

  beforeDestroy() {
    // 清除计时器
    this.stopPlayTimer && clearTimeout(this.stopPlayTimer);
    // 暂停播放
    const audioContext = this.audios[this.chapterIndex];
    audioContext && audioContext.stop();
    // 状态复原
    this.audios = [];
    this.currentValue = 0;
    this.currentTime = 0;
    this.playing = false;
    this.showTimePicker = false;
    this.playEndTime = 'n+';
  },

  methods: {
    handlePauseOrPlay() {
      // 当前播放录音
      const audioContext = this.audios[this.chapterIndex];
      if (audioContext) {
        if (this.playing) {
          audioContext.pause();
          this.playing = false;
        } else {
          audioContext.play();
          this.playing = true;
        }
      } else {
        uni.showToast({
          title: '音频文件加载失败，请退出页面重试',
          icon: 'none',
        });
      }
    },

    // 创建音频上下文
    createAudioContext(url) {
      const audioContext = uni.createInnerAudioContext();
      audioContext.autoplay = false;
      audioContext.src = url;
      audioContext.onPlay(() => {
        console.log('开始播放');
      });
      audioContext.onError((res) => {
        uni.showToast({ title: '加载音频文件失败', icon: 'none' });
      });
      // 进度更新回调函数
      audioContext.onTimeUpdate((res) => {
        const context = this.audios[this.chapterIndex];
        if (!context) return;
        // 当前已播放时间
        this.currentTime = this.hasPlayTime + context.currentTime * 1000;
        this.currentValue = (this.currentTime / this.totalTime) * 100;
        const loadNextAudio = this.audios[this.chapterIndex + 1];
        // 加载下一章节
        if (
          !loadNextAudio &&
          (context.duration <= 10 ||
            context.currentTime >= context.duration - 10) &&
          this.voices[this.chapterIndex + 1]
        ) {
          console.log('预加载下一个音频文件');
          this.audios[this.chapterIndex + 1] = this.createAudioContext(
            this.voices[this.chapterIndex + 1].url
          );
        }
      });
      // 录音播放完成
      audioContext.onEnded(() => {
        this.$store.commit('updateListen', {
          chapterIndex: this.chapterIndex + 1,
        });
        const audioContext = this.audios[this.chapterIndex];
        if (audioContext) audioContext.play();
      });
      return audioContext;
    },

    gotoBookDetail() {
      // 停止播放
      if (this.playing) {
        const audioContext = this.audios[this.chapterIndex];
        audioContext.pause();
        this.playing = false;
      }
      uni.navigateTo({
        url: `/pages/bookdetail/index?id=${this.bookid}`,
      });
    },

    // 选择播放时长
    openTimePicker() {
      this.showTimePicker = true;
    },

    // 设置定时播放
    handleSelectPlayTime(index) {
      const timeObj =
        playTimeArr[
          typeof index === 'number'
            ? index
            : get(index, 'detail.__args__')[0].result[0]
        ];
      // xx分钟之后停止播放
      this.stopPlayTimer = setTimeout(() => {
        const audioContext = this.audios[this.chapterIndex];
        audioContext.pause();
      }, timeObj.time);
      uni.showToast({ title: `将在${timeObj.text}之后停止播放`, icon: 'none' });
      this.showTimePicker = false;
    },

    handleSelectCancel() {
      this.showTimePicker = false;
    },

    // 切换章节
    handleSwitchChapter(preOrNext) {
      // 停止播放
      if (this.playing) {
        const audioContext = this.audios[this.chapterIndex];
        audioContext.pause();
        this.playing = false;
      }
      this.$emit('switch-chapter', preOrNext);
    },
  },
};
</script>

<style lang="scss">
.listen {
  &__ctrl {
    padding: 0 30rpx;

    &-slider {
      width: 100%;
      height: 6rpx;
      border-radius: 3rpx;
      margin: 0;
      // background: rgba(255,255,255,1);
      // box-shadow: 0px 0px 18px 0px rgba(153,153,153,0.3);
      // border-radius: 50%;
      &-wrap {
        width: 34rpx;
        height: 34rpx;
        background: #fff;
        box-shadow: 0rpx 0rpx 18rpx 0rpx rgba(153, 153, 153, 0.3);
        border-radius: 50%;
        display: flex;
        flex-flow: row nowrap;
        justify-content: center;
        align-items: center;
      }

      &-circle {
        width: 10rpx;
        height: 10rpx;
        background: #13d4c8;
        border-radius: 50%;
      }

      &-container {
        padding: 70rpx 0 20rpx 0;
      }

      &-time {
        display: flex;
        flex-flow: row nowrap;
        justify-content: space-between;
        align-items: center;
        font-size: 20rpx;
        color: #95a1a6;
        margin-top: 23rpx;
      }
    }

    &-btns {
      display: flex;
      flex-flow: row nowrap;
      justify-content: space-between;
      align-items: center;
      padding: 22px 15px;

      &-center {
        width: 88rpx;
        height: 88rpx;
        background: linear-gradient(
          136deg,
          rgba(112, 224, 217, 1) 0%,
          rgba(19, 212, 200, 1) 100%
        );
        border-radius: 50%;
        color: #fff;
        font-size: 54rpx;
        font-weight: bold;
        display: flex;
        flex-flow: row nowrap;
        justify-content: center;
        align-items: center;
      }

      .icon-pre,
      .icon-next {
        font-size: 48rpx;
        color: #2b3133;
        padding: 8rpx;
      }

      .icon-shichang,
      .icon-yuedu {
        font-size: 36rpx;
        color: #4b5559;
        padding: 12rpx 12rpx 8rpx 12rpx;
        font-weight: bold;
      }

      &-item {
        display: flex;
        flex-flow: column nowrap;
        justify-content: center;
        align-items: center;

        &-text {
          color: #95a1a6;
          font-size: 22rpx;
        }
      }
    }
  }
}
</style>
